package Data;

import Model.FilmeBean;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Vector;

public class FilmeDAO extends Conexao {

    public boolean isDisponivel(int id) throws SQLException {
        //Validação do id
        if (id < 1) {
            return false;
        }

        //Declaro a query
        String sql = "SELECT (T.TOTALDISPONIVEL - SUM(CASE WHEN R.DEVOLVIDO = 'F' THEN 1 ELSE 0 END)) AS DISPONIVEL "
                + " FROM TITULO T"
                + " LEFT JOIN RETIRADA R ON R.TITCOD = T.TITCOD "
                + " GROUP BY T.TOTALDISPONIVEL, R.DEVOLVIDO, T.INATIVO, T.TITCOD"
                + " HAVING T.INATIVO = 'F' AND T.TITCOD = ?";

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Coloco os parametros na consulta
        ps.setInt(1, id);

        //Executo a consulta
        ResultSet rs = ps.executeQuery();

        boolean resultado = false;

        //Verifico se atualizou algum registro
        if (rs.next()) {
            if (rs.getInt(1) > 0) {
                resultado = true;
            } else {
                resultado = false;
            }
        } else {
            //Fecho o preparedStatment
            ps.close();
            throw new SQLException("Erro na checagem de disponibilidade, a instrução não retornou nenhum registro\nParametro ID: " + id);
        }

        //Fecho o preparedStatment
        ps.close();

        return resultado;
    }

    public Vector listarFilme(String parametro, int pesquisa) throws SQLException {

        //Declaro a query
//        String sql = "select t.*, m.midiavalor from titulo t, produtora p, midia m, genero g"
//                + " where t.PRODCOD = p.PRODCOD"
//                + " and t.GENCOD = g.GENCOD"
//                + " and t.MIDIACOD = m.MIDIACOD "
//                + " and t.inativo = 'F'";

        String sql = "SELECT T.*, M.MIDIAVALOR, (T.TOTALDISPONIVEL -  SUM(CASE WHEN R.DEVOLVIDO = 'F' THEN 1 ELSE 0 END)) AS DISPONIVEL FROM TITULO T"
                + " INNER JOIN PRODUTORA P ON T.PRODCOD = P.PRODCOD"
                + " INNER JOIN MIDIA M ON T.MIDIACOD = M.MIDIACOD"
                + " INNER JOIN GENERO G ON T.GENCOD = G.GENCOD"
                + " LEFT JOIN RETIRADA R ON T.TITCOD = R.TITCOD"
                + " GROUP BY T.TITCOD, T.ANO, T.DIRETOR, T.ELENCO, T.GENCOD, "
                + " T.INATIVO, T.MIDIACOD, T.ORIGEM, T.PRODCOD, T.TEMPO_DURACAO, "
                + " T.TITULOORIGINAL, T.TITULOPORTUGUES, T.VL_ADICIONAL, T.TOTALDISPONIVEL, M.MIDIAVALOR,  P.PRODDESC"
                + " HAVING T.INATIVO = 'F'";

        //Validação
        if (parametro == null || parametro.equalsIgnoreCase("")) {
            pesquisa = -1;
        }

        //Validação do codigo, Caso tenha algo diferente de um digito pesquisa por tudo
        if (pesquisa == 0 && !parametro.matches("\\d+")) {
            pesquisa = -1;
        }

        //Checo por qual tipo de pesquisa vai ser
        switch (pesquisa) {

            //Pesquisar por codigo
            case 0:
                sql += " AND T.TITCOD = " + parametro;
                break;

            //Pesquisa por nome do filme em portugues
            case 1:
                sql += " and t.TITULOPORTUGUES like '%" + parametro + "%'";
                break;

            //Pesquisa por nome do filme em ingles
            case 2:
                sql += " and t.TITULOORIGINAL like '%" + parametro + "%'";
                break;

            //Pesquisa pelo nome da produtora
            case 3:
                sql += " and p.proddesc like '%" + parametro + "%'";
                break;

            //Diretor
            case 4:
                sql += " and t.diretor like '%" + parametro + "%'";
                break;

            //Pesquisa pelo elenco
            case 5:
                sql += " and t.elenco like '%" + parametro + "%'";
                break;

            default:
                //Pesquisa por todos os filmes
                break;
        }

        //Adicionar clausula Group By no fim
        //sql += " GROUP BY T.TITCOD, T.ANO, T.DIRETOR, T.ELENCO, T.GENCOD, T.INATIVO, T.MIDIACOD, T.ORIGEM, T.PRODCOD, T.TEMPO_DURACAO, T.TITULOORIGINAL, T.TITULOPORTUGUES, T.VL_ADICIONAL, T.TOTALDISPONIVEL, M.MIDIAVALOR";


        //Objeto para formatar moeda
        NumberFormat mf = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));

        //Crio um array de Filmes
        Vector dados = new Vector();

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Executo a consulta
        ResultSet rs = ps.executeQuery();

        //Percorre todas as linhas de resultado da query
        while (rs.next()) {
            Vector linha = new Vector();

            //Preencho as informações do filme
            linha.add(rs.getInt(1)); //Codigo
            linha.add(new MidiaDAO().getMidia(rs.getInt(3)).getDescricao()); //Descricao Midia
            //TODO colocar formatação MOEDA
            linha.add(mf.format(rs.getFloat(15))); // Valor Midia
            linha.add(rs.getInt(13));//TOTAL
            linha.add(rs.getObject(16));//DISPONIVEL
            linha.add(mf.format(rs.getFloat(12)));//VALOR ADICIONAL
            linha.add(rs.getString(5));//TITULO PORTUGUES
            linha.add(rs.getString(6));//TITULO INGLES
            linha.add(new GeneroDAO().getGenero(rs.getInt(4)).getDescricao()); // Genero
            linha.add(new ProdutoraDAO().getProdutora(rs.getInt(2)).getDescricao()); // Descricao Produtora
            linha.add(rs.getString(7));//ORIGEM
            linha.add(rs.getString(8));//ANO
            linha.add(rs.getString(9));//TEMPO DURACAO
            linha.add(rs.getString(10));//DIRETOR
            linha.add(rs.getString(11));//ELECON

            //Adicona o filme a lista
            dados.add(linha);
        }

        //Fecho o preparedStatment
        ps.close();

        //Retorno os filmes encontrados
        return dados;

    }

    public FilmeBean getFilme(int id) throws SQLException {

        //Declaro a consulta
        String sql = "select * from titulo where titcod = ?";

        //Declaro o objeto a ser retornado
        FilmeBean filme = null;

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Coloco os parametros na consulta
        ps.setObject(1, id);

        //Executo a consulta
        ResultSet rs = ps.executeQuery();

        if (rs.next()) {
            filme = new FilmeBean();

            //Preencho as informações do filme
            filme.setCodigo(rs.getInt(1));
            filme.setProdutora(new ProdutoraDAO().getProdutora(rs.getInt(2)));
            filme.setMidia(new MidiaDAO().getMidia(rs.getInt(3)));
            filme.setGenero(new GeneroDAO().getGenero(4));
            filme.setTitulo_portugues(rs.getString(5));
            filme.setTitulo_original(rs.getString(6));
            filme.setOrigem(rs.getString(7));
            filme.setAno(rs.getString(8));
            filme.setTempo_duracao(rs.getString(9));
            filme.setDiretor(rs.getString(10));
            filme.setElenco(rs.getString(11));
            filme.setValor_adiciona(rs.getFloat(12));
            filme.setTotal_disponivel(rs.getInt(13));
        }

        //Fecho o preparedStatment
        ps.close();

        //Retorno o filme
        return filme;

    }

    public FilmeBean getFilme(String nome) throws SQLException {

        //Declaro a consulta
        String sql = "select * from titulo where inativo = 'F' and tituloportugues = ?";

        //Declaro o objeto a ser retornado
        FilmeBean filme = null;

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Coloco os parametros na consulta
        ps.setObject(1, nome);

        //Executo a consulta
        ResultSet rs = ps.executeQuery();

        if (rs.next()) {
            filme = new FilmeBean();

            //Preencho as informações do filme
            filme.setCodigo(rs.getInt(1));
            filme.setProdutora(new ProdutoraDAO().getProdutora(rs.getInt(2)));
            filme.setMidia(new MidiaDAO().getMidia(rs.getInt(3)));
            filme.setGenero(new GeneroDAO().getGenero(4));
            filme.setTitulo_portugues(rs.getString(5));
            filme.setTitulo_original(rs.getString(6));
            filme.setOrigem(rs.getString(7));
            filme.setAno(rs.getString(8));
            filme.setTempo_duracao(rs.getString(9));
            filme.setDiretor(rs.getString(10));
            filme.setElenco(rs.getString(11));
            filme.setValor_adiciona(rs.getFloat(12));
            filme.setTotal_disponivel(rs.getInt(13));
        }

        //Fecho o preparedStatment
        ps.close();

        //Retorno o filme
        return filme;

    }

    public String cadastrarFilme(FilmeBean filme) throws SQLException {

        //Declaro a string sql
        String sql = "{ CALL CADASTRAR_TITULO(?,?,?,?,?,?,?,?,?,?,?,?,?) }";

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Crio o statment 
        CallableStatement cs = conn.prepareCall(sql);

        cs.setObject(1, filme.getProdutora().getCodigo());
        cs.setObject(2, filme.getMidia().getCodigo());
        cs.setObject(3, filme.getGenero().getCodigo());
        cs.setObject(4, filme.getTitulo_portugues());
        cs.setObject(5, filme.getTitulo_original());
        cs.setObject(6, filme.getOrigem());
        cs.setObject(7, filme.getAno());
        cs.setObject(8, filme.getTempo_duracao());
        cs.setObject(9, filme.getDiretor());
        cs.setObject(10, filme.getElenco());
        cs.setObject(11, filme.getValor_adiciona());
        cs.setObject(12, filme.getTotal_disponivel());
        cs.setObject(13, "");

        cs.registerOutParameter(13, Types.VARCHAR);

        cs.execute();

        String resultado = cs.getString(13);

        System.out.println(resultado);

        return resultado;

    }

    public boolean alterarFilme(FilmeBean filme) throws SQLException {
        //Validação do id
        if (filme == null || filme.getCodigo() < 0) {
            return false;
        }

        //Declaro a query
        String sql = "UPDATE TITULO"
                + " SET PRODCOD = ?, MIDIACOD = ?, GENCOD = ?, TITULOPORTUGUES = ?, TITULOORIGINAL = ?, ORIGEM = ?, ANO = ?, TEMPO_DURACAO = ?, DIRETOR = ?, ELENCO = ?, VL_ADICIONAL = ?, TOTALDISPONIVEL = ?"
                + " WHERE TITCOD = ?";

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Coloco os parametros na consulta
        ps.setObject(1, filme.getProdutora().getCodigo());
        ps.setObject(2, filme.getMidia().getCodigo());
        ps.setObject(3, filme.getGenero().getCodigo());
        ps.setObject(4, filme.getTitulo_portugues());
        ps.setObject(5, filme.getTitulo_original());
        ps.setObject(6, filme.getOrigem());
        ps.setObject(7, filme.getAno());
        ps.setObject(8, filme.getTempo_duracao());
        ps.setObject(9, filme.getDiretor());
        ps.setObject(10, filme.getElenco());
        ps.setObject(11, filme.getValor_adiciona());
        ps.setObject(12, filme.getTotal_disponivel());
        ps.setObject(13, filme.getCodigo());

        //Executo a consulta
        int resultado = ps.executeUpdate();

        //Fecho o preparedStatment
        ps.close();

        //Verifico se atualizou algum registro
        if (resultado >= 1) {
            return true;
        } else {
            return false;
        }

    }

    public boolean deletarFilme(int id) throws SQLException {
        //Validação do id
        if (id < 0) {
            return false;
        }

        //Declaro a query
        String sql = "update titulo set inativo = 'T' where titcod = ?";

        //Pego uma conexao com o banco
        Connection conn = getConexao();

        //Preparo a consulta
        PreparedStatement ps = conn.prepareStatement(sql);

        //Coloco os parametros na consulta
        ps.setInt(1, id);

        //Executo a consulta
        int resultado = ps.executeUpdate();

        //Fecho o preparedStatment
        ps.close();

        //Verifico se atualizou algum registro
        if (resultado >= 1) {
            return true;
        } else {
            return false;
        }
    }

    public boolean deletarFilme(FilmeBean filme) throws SQLException {
        //Valido o objeto
        if (filme != null && filme.getCodigo() > 0) {

            //Chamo o metodo e retorno seu resultado
            return deletarFilme(filme.getCodigo());

        } else {

            //Retorno falso por que o objeto é invalido
            return false;
        }

    }
}
